import pygame
from pygame.locals import *
import G
import Graphics
import string
import Config
import pickle
import Configurable
import Powerup
import Util
import Text
import os.path
import UI

ship = None
window = None
game = None
listenbutton = None
pressfuncs = dict()
releasefuncs = dict()
keynames = dict()
typing_mode = False
savefile = 'Settings.cfg'
specialtext = pickle.Unpickler(open('specialtext.p', 'rb')).load()

letterstoupper = dict([(chr(i), chr(i-32)) for i in range(97,123)])
lowertoupper =    {'`': '~', '1': '!', '2': '@', '3': '#', '4': '$', '5': '%',
                   '6': '^', '7': '&', '8': '*', '9': '(', '0': ')', '-': '_',
                   '=': '+', '[': '{', '}': '}', ';': ':', '\'': '\"',
                   ',': '<', '.': '>', '/': '?'}
typingkeys = (K_RETURN, K_BREAK, K_PAUSE, K_ESCAPE, K_q)
pausedkeys = (K_RETURN, K_BREAK, K_PAUSE, K_ESCAPE, K_q)
nongamekeys = (K_RETURN, K_ESCAPE, K_q)

commbuffer = ['']
commindex = 0

defkeynames = {K_ESCAPE: "Quit",
               K_q: "Main Menu",
               K_p: "Take Screenshot",
               K_RETURN: "Console",
               K_BREAK: "Pause",
               K_PAUSE: "Pause",
               K_LEFT: "Move Left",
               K_RIGHT: "Move Right",
               K_DOWN: "Move Down",
               K_UP: "Move Up",
               K_SPACE: "Shoot",
               K_LCTRL: "Toggle Alternating Fire",
               K_RCTRL: "Toggle Alternating Fire",
               K_0: "Toggle Weapon 10",
               K_1: "Toggle Weapon 1",
               K_2: "Toggle Weapon 2",
               K_3: "Toggle Weapon 3",
               K_4: "Toggle Weapon 4",
               K_5: "Toggle Weapon 5",
               K_6: "Toggle Weapon 6",
               K_7: "Toggle Weapon 7",
               K_8: "Toggle Weapon 8",
               K_9: "Toggle Weapon 9",
               K_s: "Toggle Automatic Fire",
               K_a: "Lock Target"}

changes = dict()

def apply(text):
   global commindex
   
   if len(text) > 0:
      if len(commbuffer) == 1 or text != commbuffer[-2]:
         commbuffer.insert(-1, text)
      comm_scroll()
      try:
         game.evaluate(text)
      except:
         if specialtext.has_key(text):
            if G.game.ingame:
               if specialtext[text] == 'praxiseffect':
                  Config.praxiseffect = not Config.praxiseffect
               elif specialtext[text] == 'deathray':
                  ship.equip_item(Configurable.instantiate(G.items['Death Ray']))
                  ship.invulnerable = True
            if specialtext[text] == 'money' and ship is not None:
               ship.money += 1000000

def comm_scroll(pos=None, delta=None):
   global commindex
   
   if pos is None:
      pos = len(commbuffer)-1
   
   if delta is not None:
      pos = commindex + delta
   
   commindex = Util.constrain(pos, 0, len(commbuffer)-1)
   G.game.set_typed_text(commbuffer[commindex])

def init():
   global ship
   global window
   global game
   global pressfuncs
   global releasefuncs
   
   game = G.game
   window = G.game.window

   pressfuncs = {"Quit": game.exit,
                 "Main Menu": game.quit,
                 "Take Screenshot": lambda w=window: Graphics.print_screen(w),
                 "Console": toggle_typing,
                 "Pause": G.game.pause
                }
   
   releasefuncs = dict()
   
   ship = G.player_ship
   
   if G.game.ingame:
      pressfuncs.update({"Move Left": ship.goleft,
                          "Move Right": ship.goright,
                          "Move Down": ship.godown,
                          "Move Up": ship.goup,
                          "Shoot": ship.startfiring,
                          "Toggle Alternating Fire": ship.alternate_fire,
                          "Toggle Weapon 10": lambda: ship.toggleweapon(9),
                          "Toggle Weapon 1": lambda: ship.toggleweapon(0),
                          "Toggle Weapon 2": lambda: ship.toggleweapon(1),
                          "Toggle Weapon 3": lambda: ship.toggleweapon(2),
                          "Toggle Weapon 4": lambda: ship.toggleweapon(3),
                          "Toggle Weapon 5": lambda: ship.toggleweapon(4),
                          "Toggle Weapon 6": lambda: ship.toggleweapon(5),
                          "Toggle Weapon 7": lambda: ship.toggleweapon(6),
                          "Toggle Weapon 8": lambda: ship.toggleweapon(7),
                          "Toggle Weapon 9": lambda: ship.toggleweapon(8),
                          "Toggle Automatic Fire": ship.toggle_automatic,
                          "Lock Target": ship.toggle_acquire_target
                         })

      releasefuncs.update(
               {K_LEFT: ship.goright,
                K_RIGHT: ship.goleft,
                K_UP: ship.godown,
                K_DOWN: ship.goup,
                K_SPACE: ship.stopfiring
               })
   for key, value in pressfuncs.items():
      del pressfuncs[key]
      for k, v in keynames.items():
         if v == key:
            pressfuncs[k] = value

def press(key):
   global listenbutton

   if listenbutton is not None:
      name = listenbutton.command
      
      if changes.get(key, '') == name:
         listenbutton.remove_key(key)
         changes[key] = None
      else:
         listenbutton.add_key(key)
         changes[key] = name
      
      listenbutton.deselect()
      listenbutton = None
   elif (not typing_mode or key in typingkeys) and (not G.game.paused or key in pausedkeys) and (UI.focus is None or not UI.focus.typing):
      if pressfuncs.has_key(key):
         pressfuncs[key]()
   elif typing_mode or (UI.focus is not None and UI.focus.typing):
      typed = pygame.key.name(key)
      if len(typed) == 1:
         if typed in string.ascii_lowercase:
            if pygame.key.get_mods() & (KMOD_LSHIFT | KMOD_RSHIFT | KMOD_CAPS):
               G.game.type(letterstoupper[pygame.key.name(key)])
            else:
               G.game.type(pygame.key.name(key))
         else:
            if pygame.key.get_mods() & (KMOD_LSHIFT | KMOD_RSHIFT):
               G.game.type(lowertoupper[pygame.key.name(key)])
            else:
               G.game.type(pygame.key.name(key))
      elif key == K_SPACE:
         G.game.type(' ')
      elif key == K_UP:
         comm_scroll(delta=-1)
      elif key == K_DOWN:
         comm_scroll(delta=1)
      elif key == K_BACKSPACE:
         G.game.backspace()

def release(key):
   if not typing_mode:
      if releasefuncs.has_key(key):
         releasefuncs[key]()

def save():
   global keynames
   
   G.settings['keynames'] = keynames

def save_changes():
   for k, v in changes.items():
      if v is None and keynames.has_key(k):
         del keynames[k]
      else:
         keynames[k] = v

def toggle_typing():
   global typing_mode
   
   if typing_mode:
      typing_mode = False
      apply(G.game.get_typed_text())
      pygame.key.set_repeat()
   else:
      typing_mode = True
      comm_scroll()
      pygame.key.set_repeat(350, 20)

keynames = G.settings.get('keynames', defkeynames)
